package com.rebate.dao.impl;

import java.util.List;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
import com.rebate.dao.IBaseDao;
import com.rebate.util.Page;
import com.rebate.util.QueryResult;
import com.rebate.util.ReflectUtils;

public class BaseDaoImpl<T> extends SqlMapClientDaoSupport implements IBaseDao<T> {
	
	private final String createSql = "insertSelective";
	private final String deleteSql = "deleteByPrimaryKey";
	private final String updateSql = "updateByPrimaryKeySelective";
	private final String findByIdSql = "selectByPrimaryKey";
	private final String findBySelectiveSql = "queryForListPage";
	private final String queryForListPageSql = "queryForListPage";
	public final String countSubfix = "_COUNT";
	
	protected String namespace;

	private SqlExecutor sqlExecutor;
	
	@Override
	public long create(T pojo) {
		Object id = getSqlMapClientTemplate().insert(namespace.concat(createSql), pojo);
		return id == null?0:(Long) id;
	}

	@Override
	public boolean delete(long id) {
		return getSqlMapClientTemplate().delete(namespace.concat(deleteSql), id) == 1;
	}

	@Override
	public boolean update(T pojo) {
		return getSqlMapClientTemplate().update(namespace.concat(updateSql),pojo) == 1;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T findById(long id) {
		return (T) getSqlMapClientTemplate().queryForObject(namespace.concat(findByIdSql), id);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public List<T> findBySelective(Object data) {
		return (List) getSqlMapClientTemplate().queryForList(namespace.concat(findBySelectiveSql), data);
	}

	@SuppressWarnings("hiding")
	@Override
	public <T> Page<T> queryForListPage(Page<T> page, Object obj) {
		int offset = page.getFirst();
		int pageSize = page.getPageSize();
		QueryResult<T> temp = findByQuery(offset, pageSize, obj);
		page.setResult(temp.getResult());
		page.setTotalCount(temp.getTotalCount());
		return page;
	}
	
	@SuppressWarnings({ "unchecked", "hiding" })
	private <T> QueryResult<T> findByQuery(int offset, int size, Object param){
		QueryResult<T> queryResult = new QueryResult<T>();
		String countSqlId = namespace +queryForListPageSql + countSubfix;
		Integer totalSize = (Integer)this.getSqlMapClientTemplate().queryForObject(countSqlId, param);
		if(totalSize == null ) totalSize = 0;
		queryResult.setTotalCount(totalSize);
		queryResult.setResult(getSqlMapClientTemplate().queryForList(namespace+queryForListPageSql, param, offset, size));
		return queryResult;
	}
	
	public void init() throws Exception {
		if (sqlExecutor != null) {
			SqlMapClient sqlMapClient = getSqlMapClientTemplate()
					.getSqlMapClient();
			ReflectUtils.setFieldValue(
					((SqlMapClientImpl) sqlMapClient).getDelegate(),
					"sqlExecutor", SqlExecutor.class, sqlExecutor);
		}
	}
	
	public void setSqlExecutor(SqlExecutor sqlExecutor) {
		this.sqlExecutor = sqlExecutor;
	}
	
	public void setNamespace(String namespace) {
		this.namespace = namespace.concat(".");
	}
}
